﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;


namespace Httlgd.DataCenter.Services.Core
{
    public abstract class BusinessComponentGeneric<BusinessEntityType, DataAccessorType> : BusinessComponentBase
        where BusinessEntityType : BusinessEntityBase, new()
        where DataAccessorType : IDataAccessor<BusinessEntityType>, new()
    {
        #region Constructors
        public BusinessComponentGeneric()
        {
            DA = new DataAccessorType();
        }
        #endregion

        #region Properties
        protected DataAccessorType DA { get; set; }
        #endregion

        #region Overrided Methods
        public override void Delete(DataTransferObjectBase param)
        {
            DTOKey entityKey = param as DTOKey;
            if (entityKey != null)
            {
                this.DA.Delete(((DTOKey)param).Key);
            }
            else
            {
                this.DA.Delete(((BusinessEntityBase)param).Key);
            }
        }

        public override DataTransferObjectBase Save(BusinessEntityBase param)
        {
            if (param == null) throw new Exception("Null Parameter");

            if (param.Key == null || (int)param.Key == 0)
                return this.Create(param);
            else
                return this.Update(param);
        }

        public override DataTransferObjectBase Retrieve(DataTransferObjectBase param)
        {
            DataTransferObjectBase response = default(DataTransferObjectBase);

            DTOKey entityKey = param as DTOKey;
            if (entityKey != null)
            {
                response = this.DA.Retrieve(((DTOKey)param).Key);
            }
            else
            {
                response = this.DA.Retrieve(((BusinessEntityBase)param).Key);
            }

            return response;
        }

        public override DataTransferObjectBase RetrieveList()
        {
            List<BusinessEntityType> retrievedList = DA.RetrieveAll();

            DataTransferObjectCollectionBase<BusinessEntityType> result = new DataTransferObjectCollectionBase<BusinessEntityType>();
            result.Items = retrievedList;

            return result;
        }

        public override DataTransferObjectBase Create(BusinessEntityBase businessEntity)
        {
            DataTransferObjectBase response = default(DataTransferObjectBase);
            DataTransferObjectBase error = this.ValidateBeforeInsert((BusinessEntityType)businessEntity);

            if (error != null)
            {
                return error;
            }

            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
            {
                response = this.DA.Insert((BusinessEntityType)businessEntity);
                scope.Complete();
            }

            return response;
        }

        public override DataTransferObjectBase Update(BusinessEntityBase businessEntity)
        {
            DataTransferObjectBase response = default(DataTransferObjectBase);
            DataTransferObjectBase error = this.ValidateBeforeUpdate((BusinessEntityType)businessEntity);
            if (error != null)
            {
                return error;
            }

            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
            {
                response = this.DA.Update((BusinessEntityType)businessEntity);
                scope.Complete();
            }

            return response;
        }

        public override bool IsExisted(DataTransferObjectBase param)
        {
            DTOKey entityKey = param as DTOKey;

            if (entityKey != null)
            {
                return this.DA.IsExisted(((DTOKey)param).Key);
            }

            return (this.DA.IsExisted(((BusinessEntityBase)param).Key));
        }
        #endregion

        #region Validation
        public virtual DataTransferObjectBase ValidateBeforeInsert(BusinessEntityType businessEntity)
        {
            return null;
        }

        public virtual DataTransferObjectBase ValidateBeforeUpdate(BusinessEntityType businessEntity)
        {
            return null;
        }
        #endregion
    }
}
